package com.its.us.netty.server.handler;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * 服务端接收消息处理 String类型
 *
 * @Author: master
 * @Date: 2020/11/1 19:26
 * @Version: 1.0
 */
@Component
//@ChannelHandler.Sharable
public class ChatServerHandler extends SimpleChannelInboundHandler<String> {
    // 全局单例实例化唯一
    public static ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    /**
     * 一旦链接，第一个被执行
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        String nowTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        Channel channel = ctx.channel();
        // channelGroup.writeAndFlush 会遍历并将消息发送 不需要自己遍历
        channelGroup.writeAndFlush("客户端：【" + channel.remoteAddress() + "】加入了聊天！时间：" + nowTime);
        channelGroup.add(channel);
        System.out.println("人数：" + channelGroup.size());
    }

    /**
     * 断开连接
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        String nowTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        channelGroup.writeAndFlush("客户端：【" + channel.remoteAddress() + "】离开了！时间：" + nowTime);
        // 一旦触发此事件，会自动将 channelGroup 中的channel remove 掉
    }

    /**
     * 处于活动状态
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        String nowTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        System.out.println(ctx.channel().remoteAddress() + "：上线了！时间：" + nowTime);
    }

    /**
     * 处于非活动状态
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        String nowTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        System.out.println(ctx.channel().remoteAddress() + "：离线了！时间：" + nowTime);
        System.out.println("channelGroup size:" + channelGroup.size());
    }


    /**
     * 发生异常关闭通道
     *
     * @param ctx
     * @param cause
     * @throws Exception
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.channel().close();
    }

    /**
     * 真正业务处理
     *
     * @param ctx
     * @param msg
     * @throws Exception
     */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
        String nowTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        //System.out.println("消息：" + msg.trim());
        // 获取当前通道
        Channel channel = ctx.channel();
        // 遍历 channelGroup，根据不同消息，回送不同消息
        channelGroup.forEach(ch -> {
            if (channel != ch) { // 不是当前的channel
                ch.writeAndFlush("【客户：】" + channel.remoteAddress() + "发送消息：：" + msg + "时间：" + nowTime);
            } else {
                ch.writeAndFlush("【自己发送了消息：】" + msg + " 时间：" + nowTime);
            }
        });
    }

}
